package lumis.portal.presentation.perspective;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import lumis.portal.presentation.core.AbstractLayoutFileMarkupFilter;
import lumis.portal.presentation.perspective.admin.AdminPerspectiveMarkupFilter;
import lumis.portal.presentation.perspective.publisher.PersonalizationSubHeader;
import lumis.portal.presentation.perspective.publisher.PublisherPerspectiveMarkupFilter;
import lumis.portal.presentation.perspective.user.UserPerspectiveMarkupFilter;

import org.apache.wicket.Component;

/**
 * Represents the PortalModes of each Perspective.
 * @version $Revision: 13206 $ $Date: 2011-07-06 18:38:17 -0300 (Wed, 06 Jul 2011) $
 * @since 6.0.0
 */
public enum Perspective implements Serializable
{
	/**
	 * Represents the user mode, or default mode.  
	 * This is the mode the users will usually be in.
	 * @since 6.0.0
	 */
	USER(0,"STR_USER_PERSPECTIVE", UserPerspectiveMarkupFilter.class, new IPortalMode[]{new DefaultPortalMode(IPortalMode.MODE_VIEW, "STR_VIEW_MODE_NAME", "STR_VIEW_MODE_DESCRIPTION", new ViewPagePermissionProvider(), EmptySubHeader.class, new String[]{})}),
	
	/**
	 * Represents the mode where users (non-administration) can interact
	 *  with the portal to publish or personalize the portal.
	 *  @since 6.0.0
	 */
	PUBLISHER(2,"STR_PUBLISHER_PERSPECTIVE", PublisherPerspectiveMarkupFilter.class,
			new IPortalMode[]
			{
				new DefaultPortalMode(IPortalMode.MODE_IN_CONTEXT_EDIT, "STR_INCONTEXT_EDITING", "STR_INCONTEXT_EDITING_MODE_DESCRIPTION", new PublishContentPermissionProvider(), EmptySubHeader.class, new String[]{}),
				new DefaultPortalMode(IPortalMode.MODE_PERSONALIZATION, "STR_PERSONALIZATION", "STR_PERSONALIZATION_MODE_DESCRIPTION", new PublishContentPermissionProvider(), PersonalizationSubHeader.class, new String[]{})
			}),
	/**
	 * Represents the Administration Portal Mode.
	 * @since 6.0.0
	 */
	ADMIN(1, "STR_ADMIN_PERSPECTIVE", AdminPerspectiveMarkupFilter.class, new IPortalMode[]{new DefaultPortalMode(IPortalMode.MODE_ADMINISTRATION, "STR_ADMIN_MODE_NAME", "STR_ADMIN_MODE_DESCRIPTION",  new ManagePageSecurityPermissionProvider(), EmptySubHeader.class, new String[]{"lumis.perspective.admin.safeMode"})} );

	/**
	 * Value that represents the old portal mode (0 - user, 1 - adminstration/F12).
	 * Current values are: 0 - user, 1 - admin, 2 - publisher.
	 * @since 6.0.0
	 */
	private int value;
	
	/**
	 * @since 6.0.0 
	 */
	public static Class<? extends Component> renderComponentClass;
	
	/**
	 * Key for portalmode Name. 
	 * @since 6.0.0 
	 */
	private String name;
	
	/**
	 * Markup filter for parser to use to render page.
	 * @since 6.0.0
	 */
	private Class<? extends AbstractLayoutFileMarkupFilter> markupFilterClass;
	
	/**
	 * Commands associated to this Perspective.
	 * @since 6.0.0
	 */
	private Set<IPortalMode> portalModes = Collections.emptySet();

	/**
	 * Private constructor.
	 * @param value the name of the current perspective.
	 * @param name the name of the current perspective.
	 * @param layoutFilter the markup filter to be used to render page.
	 * @param portalModes commands associated with this perspective.
	 * @since 6.0.0
	 */
	Perspective(int value, String name, Class<? extends AbstractLayoutFileMarkupFilter> markupFilterClass, IPortalMode [] portalModes)
	{
		this.value = value;
		this.name = name;
		this.markupFilterClass = markupFilterClass;
		this.portalModes = Collections.unmodifiableSet(new LinkedHashSet<IPortalMode>(Arrays.asList(portalModes)));
		//looks for the default PortalMode
		for (int i = 0; i < portalModes.length; i++)
		{
			((DefaultPortalMode)portalModes[i]).setPerspective(this);
		}
	}
	
	/**
	 * Returns all commands associated to this Perspective.
	 * @return all commands associated to this Perspective
	 * @since 6.0.0
	 */
	public Set<IPortalMode> getModes()
	{
		return this.portalModes;
	}
	
	/**
	 * Returns the integer value that represents the current Perspective.
	 * @return the integer value that represents the current Perspective.
	 * @since 6.0.0
	 */
	public int value()
	{
		return this.value;
	}
	
	/**
	 * Returns the Perspective's name key.
	 * @return the Perspective's name key.
	 * @since 6.0.0
	 */
	public String getName()
	{
		return this.name;
	}
	
	/**
	 * Returns markup filter for parser to use to render page.
	 * @return markup filter for parser to use to render page.
	 * @since 6.0.0
	 */
	public Class<? extends AbstractLayoutFileMarkupFilter> getMarkupFilterClass()
	{
		return this.markupFilterClass;
	}
	
	/**
	 * Returns a given perspective.
	 * @param perspective the id perspective to be found
	 * @return a given perspective.
	 * @since 6.0.0
	 */
	public static Perspective getPerspectiveFromValue(int perspective)
	{
		Perspective chosenPerspective = null;
		Perspective [] perspectives = Perspective.values();
		
		for (int i = 0; i < perspectives.length; i++)
		{
			if(perspectives[i].value == perspective)
			{
				chosenPerspective = perspectives[i];
				break;
			}
				
		}
		
		if(chosenPerspective == null)
		{
			throw new IllegalArgumentException("Invalid Perspective Code: " + perspective);
		}
		return chosenPerspective;
	}
	
	/**
	 * Returns a given portal mode from a mode id.
	 * @param modeCode the mode id
	 * @return the found portal mode
	 * @since 6.0.0
	 */
	public static IPortalMode getPortalModeFromCode(int modeCode)
	{
		IPortalMode portalMode = null;
		
		for (Perspective currentPerspective: Perspective.values())
		{
			Set<IPortalMode> sPortalModes = currentPerspective.getModes();
			Iterator<IPortalMode> iPortalModes = sPortalModes.iterator();
			while (iPortalModes.hasNext() && portalMode == null)
			{
				IPortalMode next = (IPortalMode) iPortalModes.next();
				if(next.getId()== modeCode)
				{
					portalMode = next;
				}
			}
		}
		
		if (portalMode == null)
		{
			throw new IllegalArgumentException("Invalid Mode Code: " + modeCode);
		}
		return portalMode;
	}
}

